package com.dz.scrm.app.config

import android.app.Activity
import android.app.Application
import android.content.Context
import androidx.multidex.MultiDex
import butterknife.ButterKnife
import com.dz.scrm.BuildConfig
import com.dz.scrm.R
import com.dz.scrm.constant.LOG_TAG
import com.dz.scrm.utils.SharedPreferencesUtil
import com.dz.scrm.push.JPushHelper
import com.liulishuo.okdownload.OkDownload
import com.liulishuo.okdownload.core.connection.DownloadOkHttp3Connection
import com.orhanobut.logger.AndroidLogAdapter
import com.orhanobut.logger.FormatStrategy
import com.orhanobut.logger.Logger
import com.orhanobut.logger.PrettyFormatStrategy
import com.scwang.smart.refresh.footer.ClassicsFooter
import com.scwang.smart.refresh.header.ClassicsHeader
import com.scwang.smart.refresh.layout.SmartRefreshLayout
import com.scwang.smart.refresh.layout.constant.SpinnerStyle
import com.squareup.leakcanary.LeakCanary
import com.squareup.leakcanary.RefWatcher
import me.jessyan.art.base.delegate.AppLifecycles
import me.jessyan.art.integration.cache.IntelligentCache
import me.jessyan.art.utils.ArtUtils
import me.jessyan.autosize.AutoSizeConfig
import me.jessyan.autosize.onAdaptListener
import me.jessyan.autosize.unit.Subunits
import me.jessyan.autosize.utils.ScreenUtils
import okhttp3.OkHttpClient
import org.litepal.LitePal
import java.security.KeyManagementException
import java.security.NoSuchAlgorithmException
import java.util.concurrent.TimeUnit
import javax.net.ssl.SSLContext
import javax.net.ssl.SSLSocketFactory

/**
 * 作者：fanda
 * 日期：2021/4/21 15:32
 * 描述：Application 级别的初始化，会动态插入到相应的生命周期
 */
class AppLifecyclesImpl : AppLifecycles {

    override fun attachBaseContext(base: Context) {
        // MultiDex 初始化
        MultiDex.install(base)
    }

    override fun onCreate(application: Application) {

        if (LeakCanary.isInAnalyzerProcess(application)) {
            // This process is dedicated to LeakCanary for heap analysis.
            // You should not init your app in this process.
            return
        }
        SharedPreferencesUtil.initPreferences(application)
        LitePal.initialize(application)
        ButterKnife.setDebug(BuildConfig.LOG_DEBUG)
        AutoSizeConfig.getInstance().setLog(BuildConfig.LOG_DEBUG)

        // 日志工具配置
        val formatStrategy: FormatStrategy = PrettyFormatStrategy.newBuilder()
                .showThreadInfo(false) // (Optional) Whether to show thread info or not. Default true
                .methodCount(0) // (Optional) How many method line to show. Default 2
                .methodOffset(7) // (Optional) Hides internal method calls up to offset. Default 5// (Optional) Global tag for every log. Default PRETTY_LOGGER
                .tag(LOG_TAG)
                .build()
        Logger.addLogAdapter(object : AndroidLogAdapter(formatStrategy) {
            override fun isLoggable(priority: Int, tag: String?): Boolean {
                // DEBUG 模式下才会打印日志
                return BuildConfig.LOG_DEBUG
            }
        })
        // 极光推送SDK
        JPushHelper.init(application, BuildConfig.LOG_DEBUG)
        //LeakCanary 内存泄露检查
        ArtUtils.obtainAppComponentFromContext(application).extras()
                .put(IntelligentCache.getKeyOfKeep(RefWatcher::class.java.name)
                        , if (BuildConfig.USE_CANARY) LeakCanary.install(application) else RefWatcher.DISABLED)

        AutoSizeConfig.getInstance() //屏幕适配监听器
                .setOnAdaptListener(object : onAdaptListener {
                    override fun onAdaptBefore(target: Any, activity: Activity) {
                        //使用以下代码, 可以解决横竖屏切换时的屏幕适配问题
                        //使用以下代码, 可支持 Android 的分屏或缩放模式, 但前提是在分屏或缩放模式下当用户改变您 App 的窗口大小时
                        //系统会重绘当前的页面, 经测试在某些机型, 某些情况下系统不会主动重绘当前页面, 所以这时您需要自行重绘当前页面
                        ScreenUtils.getScreenSize(activity) // 的参数一定要不要传 Application!!!
                        AutoSizeConfig.getInstance().screenWidth = ScreenUtils.getScreenSize(activity)[0]
                        AutoSizeConfig.getInstance().screenHeight = ScreenUtils.getScreenSize(activity)[1]
                    }

                    override fun onAdaptAfter(target: Any, activity: Activity) {}
                })
                .unitsManager
                .setSupportDP(false)
                .setSupportSP(false).supportSubunits = Subunits.MM

        initSmartRefreshLayout()
        initOkHttpDownload(application)
    }

    /**
     * 下载框架配置
     */
    private fun initOkHttpDownload(application: Application) {
        // 5.0 以下手机下载协议导致下载不了的处理
        try {
            val sslContext = SSLContext.getInstance("TLS")
            sslContext.init(null, null, null)
            val builder = OkHttpClient.Builder()
            val manager = SslContextFactory.getX509TrustManager()
            val sslSocketFactory: SSLSocketFactory = SSLSocketFactoryCompat(manager)
            builder.sslSocketFactory(sslSocketFactory, manager).readTimeout(15, TimeUnit.SECONDS).connectTimeout(15, TimeUnit.SECONDS).writeTimeout(15, TimeUnit.SECONDS)
            val downloadBuilder = OkDownload.Builder(application)
                    .connectionFactory(DownloadOkHttp3Connection.Factory().setBuilder(builder))
            OkDownload.setSingletonInstance(downloadBuilder.build())
        } catch (e: NoSuchAlgorithmException) {
            e.printStackTrace()
        } catch (e: KeyManagementException) {
            e.printStackTrace()
        }
    }

    /**
     * 全局设置刷新控件
     */
    private fun initSmartRefreshLayout() {
        SmartRefreshLayout.setDefaultRefreshHeaderCreator { context, layout ->
            layout.setEnableLoadMoreWhenContentNotFull(false)
            ClassicsHeader(context).apply {
                setPrimaryColorId(R.color.colorPrimary)
                setAccentColorId(R.color.colorPrimary)
            }
        }
        SmartRefreshLayout.setDefaultRefreshFooterCreator { context, _ ->
            ClassicsFooter(context).apply {
                setPrimaryColorId(R.color.colorPrimary)
                setAccentColorId(R.color.colorPrimary)
                spinnerStyle = SpinnerStyle.Translate
            }
        }
    }

    override fun onTerminate(application: Application) {

    }
}